﻿using Gl_mes.BLL.Mes;
using MesBSW.BLL.Mes;
using MesBSW.DAL.Kingdee;
using MesBSW.DAL.MesDB;
using MesBSW.DAL.MesDTO;
using MesBSW.Tools;
using MesBSW.View.Dialog.Mes;
using NPOI.HSSF.UserModel;
using NPOI.SS.Util;
using NPOI.XSSF.UserModel;
using Sunny.UI;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Windows.Forms;

namespace MesBSW.View.PMC
{
    public partial class OrderCompletionStatusFrm : UIPage
    {
        #region "内部变量"

        //private OrderCompletionControler _ctrl = new OrderCompletionControler();
        //private List<OrderCompletion> _search_list = new List<OrderCompletion>();
        //private object _cell_value = null;
        //private List<string> _line_list = new List<string>();
        private List<SourceProdProcessDTO> _source_List = new List<SourceProdProcessDTO>();
        private KingdeeControler _king_ctrl = new KingdeeControler();
        private ProdScheduleControler _ctrl = new ProdScheduleControler();
        private ProdProcessControler _prod_ctrl = new ProdProcessControler();

        private DataSet _ds = new DataSet();
        private List<ProdLineSetting> _line_list = new List<ProdLineSetting>();

        public DataTable aaa { get; set; }
        #endregion


        public OrderCompletionStatusFrm()
        {
            InitializeComponent();
        }

        #region "控件事件"
        /// <summary>
        /// 界面读取时，将所有生产线读取出来
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OrderCompletionStatusFrm_Load(object sender, EventArgs e)
        {
            this._line_list = this._ctrl.SearchAllProdLineSetting();
            this.dtpFillDate.Value = DateTime.Now;
            //this.chkIsComp.Checked = true;
            //this.chkNoComp.Checked = true;

            if (this._line_list != null && this._line_list.Count > 0)
            {
                List<string> tmpList = new List<string>();
                tmpList.Add("全部");
                tmpList.AddRange(this._line_list.Select(l => l.LineName).ToList());
                foreach (var item in tmpList)
                {
                    //this.cmbProdLineS.Items.Add(item);
                }
            }
        }

        /// <summary>
        /// 导入按钮事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnInputExcel_Click(object sender, EventArgs e)
        {
            try
            {
                //导入EXCEL，取得最原始的EXCEL内容
                DataTable tmpDt = this.InuptExcelFile();
                if (tmpDt != null && tmpDt.Rows.Count > 0)
                {
                    //根据表头，分割EXCEL成不同的DataTable
                    this._ds = this.AdjustDataTable(tmpDt);

                    ////根据每个DataTable中的工单号，找到MES系统中的工单信息
                    //this.SearchProdDataForDataSet(ref this._ds);

                    if (this._ds.Tables.Count > 0)
                    {
                        List<string> lineList = new List<string>();
                        foreach (DataTable dt in this._ds.Tables)
                        {
                            lineList.Add(dt.TableName);
                        }
                        this.InitProdLineCombobox(lineList);
                        if (this.cmbProdLine.Items.Count > 0)
                        {
                            this.cmbProdLine.SelectedIndex = 0;
                        }
                    }
                }
                else
                {
                    UIMessageBox.ShowWarning("您导入的EXCEL没有任何数据！");
                }
            }
            catch (Exception ex)
            {
                UIMessageBox.ShowWarning(ex.Message);
            }
        }

        /// <summary>
        /// 选择生产线时，显示导入的excel表中相应的资料
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void cmbProdLine_SelectedIndexChanged(object sender, EventArgs e)
        {
            string tmpName = this.cmbProdLine.SelectedItem.ToString();
            if (this._ds != null && this._ds.Tables.Contains(tmpName))
            {
                this.dgvInsert.DataSource = this._ds.Tables[tmpName];
            }
        }


        /// <summary>
        /// 保存排单计划
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void btnSave_Click(object sender, EventArgs e)
        {
            #region old code
            //int count = 0;
            //List<ProdScheduleDTO> saveList = new List<ProdScheduleDTO>();

            //if (this.CheckProdLineForInsert(this._ds))
            //{
            //    //如果保存的生产线是精益一线、精益二线和防水测试-包装的，复制一份，变成后段的计划
            //    DataSet tmpDs = new DataSet();
            //    foreach (DataTable tmpDt in this._ds.Tables)
            //    {
            //        var firstQuery = this._line_list.Where(l => l.LineName == tmpDt.TableName);
            //        if (firstQuery != null && firstQuery.Count() > 0)
            //        {
            //            ProdLineSetting firstLine = firstQuery.First<ProdLineSetting>();
            //            if (firstLine.LineCode.Equals("LINE_06") || firstLine.LineCode.Equals("LINE_07") || 
            //                    firstLine.LineCode.Equals("LINE_08") || firstLine.LineCode.Equals("LINE_14"))
            //            {
            //                string secondLineName = firstLine.LineCode.Equals("LINE_06") ? "LINE_10" : 
            //                                            firstLine.LineCode.Equals("LINE_07") ? "LINE_11" :
            //                                            firstLine.LineCode.Equals("LINE_08") ? "LINE_12" : "LINE_15";
            //                var secondQuery = this._line_list.Where(l => l.LineCode == secondLineName);
            //                if (secondQuery != null && secondQuery.Count() > 0)
            //                {
            //                    DataTable secondDt = tmpDt.Copy();
            //                    secondDt.TableName = secondQuery.First<ProdLineSetting>().LineName;
            //                    foreach (DataRow tmpRow in secondDt.Rows)
            //                    {
            //                        tmpRow["line_id"] = secondQuery.First<ProdLineSetting>().ID;
            //                        tmpRow["line_code"] = secondQuery.First<ProdLineSetting>().LineCode;
            //                        tmpRow["line_name"] = secondQuery.First<ProdLineSetting>().LineName;
            //                    }
            //                    tmpDs.Tables.Add(secondDt);
            //                }
            //            }
            //        }
            //    }
            //    if (tmpDs != null && tmpDs.Tables.Count > 0)
            //    {
            //        foreach (DataTable tmpDt in tmpDs.Tables)
            //        {
            //            this._ds.Tables.Add(tmpDt.Copy());
            //        }
            //    }


            //    saveList = this.GetProdScheduleForDataSet(this._ds);
            //    string errStr = this.CheckDataForInsert(saveList);
            //    if (errStr != null && errStr.Trim().Length > 0)
            //    {
            //        UIMessageBox.ShowError(errStr + "中止保存！");
            //    }
            //    else
            //    {
            //        try
            //        {
            //            count = this._ctrl.InsertProdSchedule(saveList);
            //            UIMessageBox.ShowSuccess("排单计划已经保存成功！");

            //            this.ClearData();
            //        }
            //        catch (Exception ex)
            //        {
            //            UIMessageBox.ShowError("排单计划保存失败！" + "\r\n" + ex.Message);
            //        }
            //    }
            //}
            //else
            //{
            //    UIMessageBox.ShowInfo("生产线已进行修改，但仍需要再按一次【保存】按钮！");
            //}
            #endregion

            using (MesDB ctx = new MesDB())
            {
                string prodnolist = "";

                foreach (DataGridViewRow dgvr in dgvInsert.Rows)
                {
                    if (dgvr.Cells["prod_number_dgv1"].Value != null && !string.IsNullOrEmpty(dgvr.Cells["prod_number_dgv1"].Value.ToString()))
                    {
                        string prod_number = dgvr.Cells["prod_number_dgv1"].Value.ToString();

                        var query = ctx.SourceProdProcesses.Where(x => x.ProdNumber == prod_number);

                        if (query.Count() == 0)
                        {
                            prodnolist += $"'{prod_number}',";
                        }
                    }
                }

                prodnolist = prodnolist.TrimEnd(',');

                DateTime tmpDay = this._prod_ctrl.GetCurrDateTime();
                string kingFilterStr = $"FDOCUMENTSTATUS = 'C' and FPRDORGID in (100153,1402597)";
                //if (this.txtProdNumber.Text.Trim().Length <= 0 && this.txtMtoNumber.Text.Trim().Length <= 0)
                //if (this.txtProdNumber.Text.Trim().Length <= 0)
                //{
                //    kingFilterStr = kingFilterStr + " and FAPPROVEDATE >= '" + tmpDay.AddDays(-10).ToString("yyyy-MM-dd") + "'";
                //}
                //else
                //{
                //if (this.txtProdNumber.Text.Trim().Length > 0)
                //{
                //kingFilterStr = kingFilterStr + " and fbillno like '%" + this.txtProdNumber.Text.Trim() + "%'";
                kingFilterStr = kingFilterStr + $" and fbillno in ({prodnolist})";
                //}
                //if (this.txtMtoNumber.Text.Trim().Length > 0)
                //{
                //    kingFilterStr = kingFilterStr + " and f_abc_text like '%" + this.txtProdNumber.Text.Trim() + "%'";
                //}
                //}

                List<PrdPPBom> ppbomList = await this._king_ctrl.SearchPrdPPBomByCondition(kingFilterStr);

                if (ppbomList != null && ppbomList.Count > 0)
                {
                    List<string> tmpList = ppbomList.Select(q => q.bill_no).Distinct().ToList();
                    List<SourceProdProcess> sourceList = this._prod_ctrl.SearchTargetProdForList(tmpList);
                    foreach (var item in ppbomList)
                    {
                        Console.WriteLine(item.bill_no);
                        //if (item.bill_no.Equals("BSW(TH)PM240600015"))
                        //{
                        //    Console.WriteLine("aaa");
                        //}
                        bool isEx = false;
                        if (sourceList != null && sourceList.Count > 0)
                        {
                            var tmpQuery = sourceList.Where(q => q.ProdNumber == item.bill_no);
                            if (tmpQuery != null && tmpQuery.Count() > 0)
                            {
                                isEx = true;
                            }
                        }

                        if (isEx == false)
                        {
                            this._source_List.Add(this.ChangePpbomIntoSourceProd(item));
                        }
                    }
                }

                if (this._source_List != null && this._source_List.Count > 0)
                {
                    this.UpdateGoodsLength(this._source_List);
                    //this.dgvProd.DataSource = this.ChangeSourceListToDataTable(this._source_List);
                }
                else
                {
                    UIMessageBox.ShowWarning("金蝶系统中没有找到符合条件的工单信息！");
                }

                List<SourceProdProcessDTO> saveList = this.GetSaveListForChoose(this.ChangeSourceListToDataTable(this._source_List.Distinct().ToList()));

                if (saveList != null && saveList.Count > 0)
                {
                    //string errStr = this.ChechData(saveList);
                    //if (string.IsNullOrEmpty(errStr))
                    //{

                    string errnolist = "";

                    List<SourceProdProcessDTO> saveList_copy = saveList;

                    foreach (var item in saveList_copy)
                    {
                        if ((item.GoodsLength ?? 0) <= 0)
                        {
                            string prodno = item.ProdNumber;

                            errnolist += $"{prodno},";

                            saveList = saveList.Where(x => x.ProdNumber != prodno).ToList();
                        }
                    }

                    errnolist = errnolist.TrimEnd(',');

                    try
                    {
                        int count = this._prod_ctrl.SaveSourceProdForInputKingdee(saveList);

                        if (errnolist.Length > 0)
                        {
                            this._source_List.Clear();
                            UIMessageBox.ShowSuccess($"保存成功！单据【{errnolist}】的每板可载量为0,请到物料列表维护相关数据！");
                            return;
                        }

                        UIMessageBox.ShowSuccess("工单已经全部保存成功！");
                    }
                    catch (Exception ex)
                    {
                        UIMessageBox.ShowError(ex.Message);
                    }
                    //}
                    //else
                    //{
                    //    UIMessageBox.ShowError(errStr);
                    //}
                }
                else
                {
                    UIMessageBox.ShowWarning("没有任何可以保存的工单信息！");
                }

                this._source_List.Clear();
            }
        }

        /// <summary>
        /// 更新每份工单中成品每板可载量
        /// </summary>
        /// <param name="sourceList"></param>
        private void UpdateGoodsLength(List<SourceProdProcessDTO> sourceList)
        {
            if (sourceList != null && sourceList.Count > 0)
            {
                List<string> tmpList = sourceList.Select(q => q.GoodsNumber).Distinct().ToList<string>();
                List<MatInfo> matList = this._prod_ctrl.SearchGoodsInfoForList(tmpList);
                if (matList != null && matList.Count > 0)
                {
                    foreach (var item in sourceList)
                    {
                        string orgid = item.ProdNumber.Contains("TH") ? "1402597" : "100153";
                        var tmpQuery = matList.Where(q => q.mat_number == item.GoodsNumber).Where(a => a.use_ordid == orgid);

                        if (tmpQuery.Count() == 0 && orgid == "100153")
                        {
                            orgid = "BSW";
                            tmpQuery = matList.Where(q => q.mat_number == item.GoodsNumber).Where(a => a.use_ordid == orgid);
                        }

                        if (tmpQuery != null && tmpQuery.Count() > 0 && tmpQuery.First().board_qty > 0)
                        {
                            item.GoodsLength = tmpQuery.First().board_qty;
                            if (item.targetList != null && item.targetList.Count > 0)
                            {
                                foreach (var target in item.targetList)
                                {
                                    target.GoodsLength = tmpQuery.First().board_qty;
                                }
                            }
                        }
                    }
                }
            }
        }

        /// <summary>
        /// 检查将要保存的工单是否存在问题
        /// </summary>
        /// <param name="sourceList"></param>
        /// <returns></returns>
        private string ChechData(List<SourceProdProcessDTO> sourceList)
        {
            string errStr = "";
            if (sourceList != null && sourceList.Count > 0)
            {
                foreach (var item in sourceList)
                {
                    if ((item.GoodsLength ?? 0) <= 0)
                    {
                        errStr = $"工单：{item.ProdNumber} 的每板可载量为0";
                        break;
                    }
                    else if (item.targetList is null || item.targetList.Count <= 0)
                    {
                        errStr = $"工单：{item.ProdNumber} 的目标工单不存在！";
                        break;
                    }
                    else
                    {
                        foreach (var target in item.targetList)
                        {
                            if (target.SiteGroup is null || target.SiteGroup.ID <= 0)
                            {
                                errStr = $"工单：{item.ProdNumber} 的目标工单不存在！";
                                break;
                            }
                        }
                    }
                }
            }
            return errStr;
        }

        /// <summary>
        /// 将金蝶查询出来的生产用料清单转变成工单信息
        /// </summary>
        /// <param name="ppbom"></param>
        /// <returns></returns>
        private SourceProdProcessDTO ChangePpbomIntoSourceProd(PrdPPBom ppbom)
        {
            if (ppbom != null)
            {
                SourceProdProcessDTO resBean = new SourceProdProcessDTO
                {
                    ID = 0,
                    ClientCode = string.IsNullOrEmpty(ppbom.client_number) ? "" : ppbom.client_number,
                    SalerName = string.IsNullOrEmpty(ppbom.saler_name) ? "" : ppbom.saler_name,
                    ProdNumber = string.IsNullOrEmpty(ppbom.bill_no) ? "" : ppbom.bill_no,
                    MoNumber = string.IsNullOrEmpty(ppbom.mo_bill_no) ? "" : ppbom.mo_bill_no,
                    MtoNumber = string.IsNullOrEmpty(ppbom.mto_no) ? "" : ppbom.mto_no,
                    GoodsNumber = string.IsNullOrEmpty(ppbom.material_number) ? "" : ppbom.material_number,
                    GoodsName = string.IsNullOrEmpty(ppbom.material_name) ? "" : ppbom.material_name,
                    GoodsSpe = string.IsNullOrEmpty(ppbom.material_spe) ? "" : ppbom.material_spe,
                    GoodsLength = 0,
                    OrderQty = ppbom.qty,
                    Remark = string.IsNullOrEmpty(ppbom.remark) ? "" : ppbom.remark,
                    OrgNumber = ppbom.prod_orgid.ToString(),
                    DeptId = 13,
                    targetList = new List<TargetProdProcessDTO>()
                    {
                        new TargetProdProcessDTO
                        {
                            ID = 0,
                            ParentID = 0,
                            ClientCode = string.IsNullOrEmpty(ppbom.client_number) ? "" : ppbom.client_number,
                            SalerName = string.IsNullOrEmpty(ppbom.saler_name) ? "" : ppbom.saler_name,
                            ProdNumber = string.IsNullOrEmpty(ppbom.bill_no) ? "" : ppbom.bill_no,
                            MoNumber = string.IsNullOrEmpty(ppbom.mo_bill_no) ? "" : ppbom.mo_bill_no,
                            MtoNumber = string.IsNullOrEmpty(ppbom.mto_no) ? "" : ppbom.mto_no,
                            GoodsNumber = string.IsNullOrEmpty(ppbom.material_number) ? "" : ppbom.material_number,
                            GoodsName = string.IsNullOrEmpty(ppbom.material_name) ? "" : ppbom.material_name,
                            GoodsSpe = string.IsNullOrEmpty(ppbom.material_spe) ? "" : ppbom.material_spe,
                            GoodsLength = 0,
                            OrderQty = ppbom.qty,
                            ProdQty = ppbom.qty,
                            Remark = string.IsNullOrEmpty(ppbom.remark) ? "" : ppbom.remark,
                            ProdStatusID = 13,
                            UrgentStatusID = 8,
                            ErrStatusID = 19,
                            CurrSiteID = 0,
                            OldNumber = ppbom.old_number,
                            OrgNumber = ppbom.prod_orgid.ToString(),
                            DeptId = 13,
                            SiteGroup = new SiteGroupDTO
                            {
                                ID = 1
                            }
                        }
                    }
                };
                return resBean;
            }
            else
            {
                return null;
            }
        }

        /// <summary>
        /// 将需要保存的工单信息转化成DataTable
        /// </summary>
        /// <param name="sourceList"></param>
        /// <returns></returns>
        private DataTable ChangeSourceListToDataTable(List<SourceProdProcessDTO> sourceList)
        {
            DataTable resDt = new DataTable();
            resDt.Columns.Add("is_choose", typeof(int));
            resDt.Columns.Add("index", typeof(int));
            resDt.Columns.Add("id", typeof(int));
            resDt.Columns.Add("prod_number", typeof(string));
            resDt.Columns.Add("mo_number", typeof(string));
            resDt.Columns.Add("mto_number", typeof(string));
            resDt.Columns.Add("goods_number", typeof(string));
            resDt.Columns.Add("goods_name", typeof(string));
            resDt.Columns.Add("goods_spe", typeof(string));
            resDt.Columns.Add("goods_length", typeof(decimal));
            resDt.Columns.Add("order_qty", typeof(decimal));
            resDt.Columns.Add("remark", typeof(string));

            if (sourceList != null && sourceList.Count > 0)
            {
                int index = 1;
                foreach (var item in sourceList.OrderBy(q => q.ProdNumber))
                {
                    DataRow addRow = resDt.NewRow();
                    addRow["is_choose"] = 1;
                    addRow["index"] = index;
                    addRow["id"] = item.ID;
                    addRow["prod_number"] = item.ProdNumber;
                    addRow["mo_number"] = item.MoNumber;
                    addRow["mto_number"] = item.MtoNumber;
                    addRow["goods_number"] = item.GoodsNumber;
                    addRow["goods_name"] = item.GoodsName;
                    addRow["goods_spe"] = item.GoodsSpe;
                    addRow["goods_length"] = Math.Round(item.GoodsLength ?? 0, 3);
                    addRow["order_qty"] = Math.Round(item.OrderQty ?? 0, 3);
                    addRow["remark"] = item.Remark;
                    resDt.Rows.Add(addRow);
                    index++;
                }
            }
            return resDt;
        }

        /// <summary>
        /// 从界面列表中提取需要保存的工单
        /// </summary>
        /// <param name="sourceDt"></param>
        /// <returns></returns>
        private List<SourceProdProcessDTO> GetSaveListForChoose(DataTable sourceDt)
        {
            List<SourceProdProcessDTO> resList = new List<SourceProdProcessDTO>();
            if (sourceDt != null && sourceDt.Rows.Count > 0 && this._source_List != null && this._source_List.Count > 0)
            {
                foreach (DataRow itemRow in sourceDt.Rows)
                {
                    if (itemRow["is_choose"] != DBNull.Value && int.TryParse(itemRow["is_choose"].ToString(), out int tmpInt) && tmpInt == 1)
                    {
                        var tmpQuery = this._source_List.Where(q => q.ProdNumber == itemRow["prod_number"].ToString());
                        if (tmpQuery != null && tmpQuery.Count() > 0)
                        {
                            resList.Add(tmpQuery.First());
                        }
                    }
                }
            }
            return resList;
        }


        /// <summary>
        /// 根据条件查询数据
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnSearchScan_Click(object sender, EventArgs e)
        {
            //if (this.chkIsComp.Checked == false && this.chkNoComp.Checked == false)
            //{
            //    UIMessageBox.ShowWarning("请选择【未完成】或【已完成】后再做查询操作！");
            //}
            //else
            //{
            //    DateTime? tmpDay = this.dtpFillDateS.Checked == true ? (DateTime?)this.dtpFillDateS.Value.Date : null;
            //    string prodNo = this.txtProdNumber.Text.Trim();
            //    int lineID = 0;
            //    int isComp = this.chkIsComp.Checked == true && this.chkNoComp.Checked == true ? 2 : this.chkIsComp.Checked == true ? 1 : 0;


            //    if (this.cmbProdLineS.Text != null && this.cmbProdLineS.Text.Length > 0)
            //    {
            //        var query = this._line_list.Where(l => l.LineName == this.cmbProdLineS.Text);
            //        if (query != null && query.Count() > 0)
            //        {
            //            lineID = query.First().ID;
            //        }
            //    }

            //    List<ProdScheduleDTO> scheList = this._ctrl.SearchProdSchedureForCondition(lineID, tmpDay, prodNo, isComp);
            //    if (scheList != null && scheList.Count > 0)
            //    {
            //        this.dgvSearch.DataSource = this.ListToDataTable(scheList);
            //        UIMessageBox.ShowSuccess("排单计划已经查询完毕！");
            //    }
            //    else
            //    {
            //        UIMessageBox.ShowError("没有找到合符条件的排单计划！");
            //    }
            //}
        }

        /// <summary>
        /// 删除排单计划
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnDelete_Click(object sender, EventArgs e)
        {
            List<int> idList = new List<int>();
            int tmpInt = 0;
            //if (this.dgvSearch.Rows.Count > 0)
            //{
            //    foreach (DataGridViewRow item in this.dgvSearch.Rows)
            //    {
            //        DataRow tmpRow = (item.DataBoundItem as DataRowView).Row;
            //        if (tmpRow["is_choose"] != DBNull.Value && bool.Parse(tmpRow["is_choose"].ToString()) == true)
            //        {
            //            if (tmpRow["id"] != DBNull.Value && int.TryParse(tmpRow["id"].ToString(), out tmpInt) == true && int.Parse(tmpRow["id"].ToString()) > 0)
            //            {
            //                idList.Add(int.Parse(tmpRow["id"].ToString()));
            //            }
            //        }
            //    }
            //}

            if (idList != null && idList.Count > 0)
            {
                try
                {
                    int count = this._ctrl.DeleteProdScheduleForID(idList);
                    UIMessageBox.ShowSuccess("排单计划删除成功！");

                    this.ClearData();
                }
                catch (Exception ex)
                {
                    UIMessageBox.ShowError("删除排单计划失败！" + "\r\n" + ex.Message);
                }
            }
            else
            {
                UIMessageBox.ShowWarning("请在查询列表中选择后再做删除操作！");
            }
        }

        /// <summary>
        /// 清空界面数据 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnClear_Click(object sender, EventArgs e)
        {
            this.ClearData();
        }

        /// <summary>
        /// 注册界面的快捷键
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OrderCompletionStatusFrm_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Alt == true)
            {
                if (e.KeyCode == Keys.I)
                {
                    this.btnInputExcel_Click(sender, e);
                }
                else if (e.KeyCode == Keys.S)
                {
                    this.btnSave_Click(sender, e);
                }
                else if (e.KeyCode == Keys.Q)
                {
                    this.btnSearchScan_Click(sender, e);
                }
                else if (e.KeyCode == Keys.R)
                {
                    this.btnClear_Click(sender, e);
                }
                else if (e.KeyCode == Keys.O)
                {
                    this.btnOutput_Click(sender, e);
                }
            }
        }
        #endregion

        #region "内部方法"
        /// <summary>
        /// 导入EXCEL文件
        /// </summary>
        /// <returns></returns>
        private DataTable InuptExcelFile()
        {
            DataTable resDt = new DataTable();

            //打开文件选择框，选择EXCEL文档
            System.Windows.Forms.OpenFileDialog openDia = new System.Windows.Forms.OpenFileDialog();
            openDia.Filter = "*.xlsx|*.xlsx|*.xls|*.xls";
            openDia.Title = "选择文件";
            openDia.ShowDialog(this);
            string fileName = openDia.FileName;
            if (fileName.Trim().Length > 0)
            {
                //取得EXCEL档中所有Sheet，打开Sheet选择框，让用户选择需要导入的Sheet
                List<string> sheetList = ExcelTools.ReadExcelSheetName(fileName);
                List<string> chooseList = new List<string>();
                if (sheetList != null && sheetList.Count == 1)
                {
                    chooseList.Add(sheetList[0]);
                }
                else if (sheetList.Count > 1)
                {
                    ExcelSheetChooseDia tmpDia = new ExcelSheetChooseDia(sheetList);
                    tmpDia.ShowDialog();
                    chooseList = tmpDia.ChooseList;
                }

                //导入
                if (chooseList != null && chooseList.Count > 0)
                {
                    foreach (var tmpStr in chooseList)
                    {
                        DataTable tmpDt = ExcelTools.ReadExcelToDataTableNoColumn(fileName, tmpStr);
                        if (tmpDt != null)
                        {
                            resDt.Merge(tmpDt);
                        }
                    }
                }
                else
                {
                    throw new Exception("尚未选择要导入的EXCEL页签，中止导入！");
                }
            }
            else
            {
                throw new Exception("没有选择需要导入的EXCEL文件！");
            }

            return resDt;
        }

        /// <summary>
        /// 根据导入的EXCEL表初始化生产线下拉列表
        /// </summary>
        /// <param name="lineList"></param>
        private void InitProdLineCombobox(List<string> lineList)
        {
            this.cmbProdLine.Items.Clear();
            if (lineList != null && lineList.Count > 0)
            {
                foreach (string line in lineList)
                {
                    this.cmbProdLine.Items.Add(line);
                }
            }
        }

        /// <summary>
        /// 整理导入的excel，让它成为规则的DataTable
        /// </summary>
        /// <param name="dt"></param>
        /// <returns></returns>
        private DataSet AdjustDataTable(DataTable dt)
        {
            DateTime tmpDay = this.dtpFillDate.Value.Date;
            DateTime prodDate = DateTime.Now;
            DataSet resDs = new DataSet();
            if (dt != null && dt.Rows.Count > 0)
            {
                List<TableInfo> infoList = new List<TableInfo>();

                List<int> beginIndexs = new List<int>();
                foreach (DataRow tmpRow in dt.Rows)
                {
                    if (tmpRow["Column00001"].ToString().Equals("业务员"))
                    {
                        beginIndexs.Add(dt.Rows.IndexOf(tmpRow));
                    }
                }

                if (beginIndexs != null && beginIndexs.Count > 0)
                {
                    for (int i = 0; i < beginIndexs.Count; i++)
                    {
                        if (beginIndexs[i] >= 1)
                        {
                            int endRowIndex = i == beginIndexs.Count - 1 ? dt.Rows.Count - 5 : beginIndexs[i + 1] - 3;
                            string tableName = "";
                            foreach (DataColumn tmpClu in dt.Columns)
                            {
                                if (dt.Rows[beginIndexs[i]][tmpClu.ColumnName] != DBNull.Value && dt.Rows[beginIndexs[i]][tmpClu.ColumnName].ToString().Trim().Length > 0)
                                {
                                    //tableName = dt.Rows[beginIndexs[i]][tmpClu.ColumnName].ToString().Trim();
                                    tableName = "组装";
                                    break;
                                }
                            }

                            DataTable tmpDt = InitDataTableColumn();
                            tmpDt.TableName = tableName;

                            string prodCluName = "";
                            string prodDateName1 = "";
                            string prodDateName2 = "";
                            ProdLineSetting lineBean = null;
                            if (this._line_list != null && this._line_list.Count > 0)
                            {
                                var lineQuery = this._line_list.Where(l => tableName.Contains(l.ReportName));
                                if (lineQuery != null && lineQuery.Count() > 0)
                                {
                                    lineBean = lineQuery.First();
                                }
                            }
                            for (int k = 0; k < dt.Columns.Count; k++)
                            {
                                Debug.WriteLine(dt.Rows[beginIndexs[i]][k].ToString() + "-------" + dt.Rows[beginIndexs[i] + 1][k].ToString());
                                if (dt.Rows[beginIndexs[i]][k].ToString().Equals("工单号"))
                                {
                                    prodCluName = dt.Columns[k].ColumnName.ToString();
                                }
                                else
                                {
                                    if (lineBean != null && dt.Rows[beginIndexs[i] + 1][k].ToString().Contains(lineBean.ProdDateName))
                                    {
                                        if (prodDateName1 != null && prodDateName1.Trim().Length > 0)
                                        {
                                            prodDateName2 = dt.Columns[k].ColumnName.ToString();
                                        }
                                        else
                                        {
                                            prodDateName1 = dt.Columns[k].ColumnName.ToString();
                                        }
                                    }
                                }
                            }

                            if (beginIndexs[i] + 2 <= endRowIndex)
                            {
                                int count = 1;
                                for (int j = beginIndexs[i] + 2; j <= endRowIndex; j++)
                                {
                                    if (prodCluName != null && prodCluName.Trim().Length > 0 && dt.Rows[j][prodCluName] != DBNull.Value && dt.Rows[j][prodCluName].ToString().Trim().Length > 0)
                                    {
                                        DataRow addRow = tmpDt.NewRow();
                                        addRow["index"] = count;
                                        addRow["id"] = 0;
                                        addRow["line_name"] = tableName;
                                        addRow["fill_date"] = tmpDay.ToString("yyyy-MM-dd");
                                        addRow["prod_number"] = dt.Rows[j][prodCluName].ToString();
                                        addRow["remark"] = "";
                                        addRow["remark_pmc"] = "";
                                        addRow["is_del"] = 0;
                                        addRow["is_comp"] = 0;
                                        addRow["remark"] = "未收到";
                                        addRow["remark_pmc"] = "";
                                        addRow["remark_bus"] = "";
                                        addRow["prod_date1"] = "";
                                        addRow["prod_date2"] = "";

                                        if (prodDateName1 != null && prodDateName1.Trim().Length > 0 &&
                                                dt.Rows[j][prodDateName1] != DBNull.Value && DateTime.TryParse(dt.Rows[j][prodDateName1].ToString(), out prodDate))
                                        {
                                            addRow["prod_date1"] = DateTime.Parse(dt.Rows[j][prodDateName1].ToString()).ToString("yyyy-MM-dd");
                                        }
                                        if (prodDateName2 != null && prodDateName2.Trim().Length > 0 &&
                                                dt.Rows[j][prodDateName2] != DBNull.Value && DateTime.TryParse(dt.Rows[j][prodDateName2].ToString(), out prodDate))
                                        {
                                            addRow["prod_date2"] = DateTime.Parse(dt.Rows[j][prodDateName2].ToString()).ToString("yyyy-MM-dd");
                                        }

                                        addRow["goods_number"] = dt.Rows[j]["Column00005"].ToString();
                                        addRow["goods_spe"] = dt.Rows[j]["Column00006"].ToString();
                                        addRow["remark"] = dt.Rows[j]["Column00019"].ToString();
                                        addRow["order_qty"] = dt.Rows[j]["Column00007"].ToString();

                                        tmpDt.Rows.Add(addRow);
                                        count++;
                                    }
                                }
                            }

                            if (resDs != null && resDs.Tables.Count > 0 && resDs.Tables.Contains(tableName))
                            {
                                resDs.Tables[tableName].Merge(tmpDt);
                            }
                            else
                            {
                                resDs.Tables.Add(tmpDt);
                            }
                        }

                    }
                }
            }
            return resDs;
        }


        /// <summary>
        /// 通过工单号查找相应的资料
        /// </summary>
        /// <param name="ds"></param>
        private void SearchProdDataForDataSet(ref DataSet ds)
        {
            DateTime tmpDay = this._ctrl.GetCurrDateTime();
            List<string> prodList = new List<string>();

            if (ds != null && ds.Tables.Count > 0)
            {
                foreach (DataTable tmpDt in ds.Tables)
                {
                    if (tmpDt != null && tmpDt.Rows.Count > 0)
                    {
                        tmpDay = DateTime.TryParse(tmpDt.Rows[0]["fill_date"].ToString(), out tmpDay) ? DateTime.Parse(tmpDt.Rows[0]["fill_date"].ToString()) : tmpDay;
                        foreach (DataRow tmpRow in tmpDt.Rows)
                        {
                            string tmpStr = tmpRow["prod_number"].ToString();
                            string[] strArray = tmpStr.Split("-");
                            string prodNumber = "";
                            if (strArray[0].Length == 9)
                            {
                                string tmpYear = tmpDay.ToString("yyyy").Substring(2, 2);
                                if (tmpDay.Month < int.Parse(strArray[0].Substring(2, 2)))
                                {
                                    tmpYear = tmpDay.AddYears(-1).ToString("yyyy").Substring(2, 2);
                                }
                                prodNumber = "GL01PM" + tmpYear + strArray[0].Substring(2, 7);
                            }
                            else if (strArray[0].Length == 11)
                            {
                                prodNumber = "GL01PM" + strArray[0].Substring(2, 9);
                            }
                            else
                            {
                                prodNumber = strArray[0];
                            }
                            if (strArray.Length > 1)
                            {
                                prodNumber = prodNumber + "-" + strArray[1];
                            }

                            prodList.Add(prodNumber);
                            tmpRow["prod_number"] = prodNumber;
                        }
                    }
                }
            }

            List<TargetProdProcess> targetList = this._ctrl.SearchTargetForProdNo(prodList);
            if (targetList != null && targetList.Count > 0)
            {
                foreach (DataTable tmpDt in ds.Tables)
                {
                    foreach (DataRow tmpRow in tmpDt.Rows)
                    {
                        var tmpQuery = targetList.Where(t => t.ProdNumber == tmpRow["prod_number"].ToString());
                        if (tmpQuery != null && tmpQuery.Count() > 0)
                        {
                            tmpRow["target_id"] = tmpQuery.First<TargetProdProcess>().ID;
                            tmpRow["saler_name"] = tmpQuery.First<TargetProdProcess>().SalerName;
                            tmpRow["client_code"] = tmpQuery.First<TargetProdProcess>().ClientCode;
                            tmpRow["mto_number"] = tmpQuery.First<TargetProdProcess>().MtoNumber;
                            tmpRow["mo_number"] = tmpQuery.First<TargetProdProcess>().MoNumber;
                            tmpRow["goods_number"] = tmpQuery.First<TargetProdProcess>().GoodsNumber;
                            tmpRow["old_number"] = tmpQuery.First<TargetProdProcess>().OldNumber;
                            tmpRow["goods_name"] = tmpQuery.First<TargetProdProcess>().GoodsName;
                            tmpRow["goods_spe"] = tmpQuery.First<TargetProdProcess>().GoodsSpe;
                            tmpRow["order_qty"] = Math.Round((tmpQuery.First<TargetProdProcess>().OrderQty ?? 0), 3);
                            tmpRow["goods_length"] = Math.Round((tmpQuery.First<TargetProdProcess>().GoodsLength ?? 0), 3);
                            tmpRow["prod_qty"] = Math.Round((tmpQuery.First<TargetProdProcess>().ProdQty ?? 0), 3); ;
                        }
                    }
                }
            }

        }

        /// <summary>
        /// 初始化DataTable，导入EXCEL时使用
        /// </summary>
        /// <returns></returns>
        private DataTable InitDataTableColumn()
        {
            DataTable resDt = new DataTable();
            resDt.Columns.Add("index", typeof(int));
            resDt.Columns.Add("id", typeof(int));
            resDt.Columns.Add("line_id", typeof(int));
            resDt.Columns.Add("line_code", typeof(string));
            resDt.Columns.Add("line_name", typeof(string));
            resDt.Columns.Add("fill_date", typeof(string));
            resDt.Columns.Add("prod_date1", typeof(string));
            resDt.Columns.Add("prod_date2", typeof(string));
            resDt.Columns.Add("target_id", typeof(int));
            resDt.Columns.Add("saler_name", typeof(string));
            resDt.Columns.Add("client_code", typeof(string));
            resDt.Columns.Add("mto_number", typeof(string));
            resDt.Columns.Add("mo_number", typeof(string));
            resDt.Columns.Add("prod_number", typeof(string));
            resDt.Columns.Add("goods_number", typeof(string));
            resDt.Columns.Add("old_number", typeof(string));
            resDt.Columns.Add("goods_name", typeof(string));
            resDt.Columns.Add("goods_spe", typeof(string));
            resDt.Columns.Add("order_qty", typeof(decimal));
            resDt.Columns.Add("goods_length", typeof(decimal));
            resDt.Columns.Add("prod_qty", typeof(decimal));
            resDt.Columns.Add("remark", typeof(string));
            resDt.Columns.Add("remark_pmc", typeof(string));
            resDt.Columns.Add("remark_bus", typeof(string));
            resDt.Columns.Add("is_del", typeof(int));
            resDt.Columns.Add("is_comp", typeof(int));
            resDt.Columns.Add("comp_date", typeof(string));
            return resDt;
        }


        /// <summary>
        /// 将数据由DataRow转化成实体类
        /// </summary>
        /// <param name="dr"></param>
        /// <returns></returns>
        private ProdScheduleDTO DataRowToBean(DataRow dr)
        {
            if (dr["prod_number"].ToString().Equals("GL01PM240401684"))
            {
                Console.WriteLine("aaaa");
            }
            List<string> groupList1 = new List<string>(new string[] { "LINE_01", "LINE_02", "LINE_03", "LINE_04", "LINE_06", "LINE_07", "LINE_08", "LINE_13", "LINE_14" });
            List<string> groupList2 = new List<string>(new string[] { "LINE_10", "LINE_11", "LINE_12", "LINE_05", "LINE_15" });
            ProdScheduleDTO resBean = new ProdScheduleDTO();
            DateTime tmpDay = DateTime.Now;

            if (dr != null)
            {
                resBean.ID = dr["id"] != DBNull.Value ? int.Parse(dr["id"].ToString()) : 0;
                resBean.LineID = dr["line_id"] != DBNull.Value ? int.Parse(dr["line_id"].ToString()) : 0;
                resBean.LineCode = dr["line_code"] != DBNull.Value ? dr["line_code"].ToString() : "";
                resBean.LineName = dr["line_name"] != DBNull.Value ? dr["line_name"].ToString() : "";
                resBean.FillDate = dr["fill_date"] != DBNull.Value && DateTime.TryParse(dr["fill_date"].ToString(), out tmpDay) ? DateTime.Parse(dr["fill_date"].ToString()).Date : DateTime.Now.Date;
                resBean.ProdDate = null;
                if (groupList1.Contains(resBean.LineCode) && dr["prod_date1"] != DBNull.Value && DateTime.TryParse(dr["prod_date1"].ToString(), out tmpDay))
                {
                    resBean.ProdDate = DateTime.Parse(dr["prod_date1"].ToString()).Date;
                }
                else if (groupList2.Contains(resBean.LineCode) && dr["prod_date2"] != DBNull.Value && DateTime.TryParse(dr["prod_date2"].ToString(), out tmpDay))
                {
                    resBean.ProdDate = DateTime.Parse(dr["prod_date2"].ToString()).Date;
                }
                resBean.Remark = dr["remark"] != DBNull.Value ? dr["remark"].ToString().Trim() : "";
                resBean.IsDel = 0;
                resBean.RemarkPMC = "";
                resBean.RemarkBus = "";

                resBean.ProdID = dr["target_id"] != DBNull.Value ? int.Parse(dr["target_id"].ToString()) : 0;
                resBean.ProdNumber = dr["prod_number"] != DBNull.Value ? dr["prod_number"].ToString() : "";
                resBean.IsComp = dr["is_comp"] != DBNull.Value ? int.Parse(dr["is_comp"].ToString()) : 0;
                resBean.CompDate = dr["comp_date"] != DBNull.Value && DateTime.TryParse(dr["comp_date"].ToString(), out tmpDay) ? DateTime.Parse(dr["comp_date"].ToString()).Date : DateTime.Now.Date;

                resBean.TargetProdProcess = new TargetProdProcess();
                resBean.TargetProdProcess.ID = dr["target_id"] != DBNull.Value ? int.Parse(dr["target_id"].ToString()) : 0;
                resBean.TargetProdProcess.ProdNumber = dr["prod_number"] != DBNull.Value ? dr["prod_number"].ToString() : "";
                resBean.TargetProdProcess.GoodsNumber = dr["goods_number"] != DBNull.Value ? dr["goods_number"].ToString() : "";
                resBean.TargetProdProcess.OrderQty = dr["order_qty"] != DBNull.Value ? decimal.Parse(dr["order_qty"].ToString()) : 0;
            }

            return resBean;
        }

        /// <summary>
        /// 从界面列表中取得ProdSchedule
        /// </summary>
        /// <param name="ds"></param>
        /// <returns></returns>
        private List<ProdScheduleDTO> GetProdScheduleForDataSet(DataSet ds)
        {
            List<ProdScheduleDTO> resList = new List<ProdScheduleDTO>();
            if (ds != null && ds.Tables.Count > 0)
            {
                foreach (DataTable tmpDt in ds.Tables)
                {
                    if (tmpDt != null && tmpDt.Rows.Count > 0)
                    {
                        foreach (DataRow tmpRow in tmpDt.Rows)
                        {
                            ProdScheduleDTO tmpBean = this.DataRowToBean(tmpRow);
                            resList.Add(tmpBean);
                        }
                    }
                }
            }

            if (resList != null && resList.Count > 0)
            {
                List<int> ids = resList.Select(r => r.ProdID).ToList();
                List<SourcePPCycle> sourceList = this._ctrl.SearchSourcePPCycleForTargetID(ids);
                if (sourceList != null && sourceList.Count > 0)
                {
                    foreach (var item in resList)
                    {
                        var sourceQuery = sourceList.Where(s => item.ProdNumber.Contains(s.ProdNumber));
                        if (sourceQuery != null && sourceQuery.Count() > 0)
                        {
                            item.SourcePPCycle = sourceQuery.First<SourcePPCycle>();
                        }
                    }
                }
            }

            List<ProdCycle> cycleList = this._ctrl.SearchAllProdCycle();
            if (cycleList != null && cycleList.Count > 0)
            {
                foreach (var item in resList)
                {
                    if ((item.LineName.Contains("SMT") || item.LineName.Contains("COB")) && item.SourcePPCycle != null)
                    {
                        int isMatWait = item.SourcePPCycle.OrderDate.Date < item.FillDate.AddDays(-1).Date ? 0 : 1;
                        var cycleQuery = cycleList.Where(c => c.IsComplete == isMatWait && c.IsCOB == item.SourcePPCycle.IsCOB &&
                                                                c.MinQty < item.TargetProdProcess.OrderQty && item.TargetProdProcess.OrderQty <= c.MaxQty);
                        if (item.SourcePPCycle.ProdType.Equals("配件与组件"))
                        {
                            cycleQuery = cycleQuery.Where(q => q.ProdType == "配件与组件");
                        }
                        else if (item.SourcePPCycle.ProdType.Equals("不防水"))
                        {
                            cycleQuery = cycleQuery.Where(q => q.ProdType == "不防水" && q.DeptID == item.SourcePPCycle.DeptForGoods);
                        }
                        else
                        {
                            cycleQuery = cycleQuery.Where(q => q.ProdType == "防水" && q.DeptID == item.SourcePPCycle.DeptForGoods);
                        }

                        if (cycleQuery != null && cycleQuery.Count() > 0)
                        {
                            ProdCycle cycleBean = cycleQuery.First<ProdCycle>();
                            item.ProdCycle = cycleBean;
                            item.SourcePPCycle.IsComplete = isMatWait;
                            item.SourcePPCycle.MatWaitDate = item.SourcePPCycle.OrderDate.AddDays(Convert.ToDouble(Math.Ceiling(cycleBean.MatWaitDays ?? 0)));
                            item.SourcePPCycle.SmtDate = item.SourcePPCycle.OrderDate.AddDays(Convert.ToDouble(Math.Ceiling((cycleBean.MatWaitDays ?? 0) + (cycleBean.SmtDays ?? 0))));
                            item.SourcePPCycle.WeldDate = item.SourcePPCycle.OrderDate.AddDays(Convert.ToDouble(Math.Ceiling((cycleBean.MatWaitDays ?? 0) + (cycleBean.SmtDays ?? 0) + (cycleBean.WeldDays ?? 0))));
                            item.SourcePPCycle.TestDate = item.SourcePPCycle.OrderDate.AddDays(Convert.ToDouble(Math.Ceiling((cycleBean.MatWaitDays ?? 0) + (cycleBean.SmtDays ?? 0) +
                                                                                                                                (cycleBean.WeldDays ?? 0) + (cycleBean.TestDays ?? 0))));
                            item.SourcePPCycle.PackDate = item.SourcePPCycle.OrderDate.AddDays(Convert.ToDouble(Math.Ceiling((cycleBean.MatWaitDays ?? 0) + (cycleBean.SmtDays ?? 0) +
                                                                                                                                (cycleBean.WeldDays ?? 0) + (cycleBean.TestDays ?? 0) + (cycleBean.PackDays ?? 0))));
                            item.SourcePPCycle.ErrDays = cycleBean.ErrDays ?? 0;
                            item.SourcePPCycle.PlanDate = item.SourcePPCycle.OrderDate.AddDays(Convert.ToDouble(Math.Ceiling((cycleBean.MatWaitDays ?? 0) + (cycleBean.SmtDays ?? 0) +
                                                                                                                                (cycleBean.WeldDays ?? 0) + (cycleBean.TestDays ?? 0) +
                                                                                                                                (cycleBean.PackDays ?? 0) + (cycleBean.ErrDays ?? 0))));
                            item.SourcePPCycle.EndDate = item.SourcePPCycle.PlanDate;
                        }
                    }
                }
            }

            return resList;
        }


        /// <summary>
        /// 新增排单计划时，检查导入的生产线与MES系统中的生产线是否一致
        /// </summary>
        /// <param name="ds"></param>
        /// <returns></returns>
        private Boolean CheckProdLineForInsert(DataSet ds)
        {
            Boolean canSave = true;
            List<string> lineList = new List<string>();
            if (ds != null)
            {
                foreach (DataTable dt in ds.Tables)
                {
                    lineList.Add(dt.TableName);
                }
            }

            if (lineList != null && lineList.Count > 0)
            {
                List<string> tmpList = new List<string>();
                foreach (var tmpLine in lineList)
                {
                    var lineQuery = this._line_list.Where(l => tmpLine.Contains(l.ReportName));
                    if (tmpLine.Contains("精益一线") || tmpLine.Contains("精益二线") || tmpLine.Contains("防水后测试-包装") || tmpLine.Contains("精益线"))
                    {
                        lineQuery = lineQuery.Where(l => l.LineName == l.ReportName + "（前）");
                    }

                    if (lineQuery != null && lineQuery.Count() > 0)
                    {
                        DataTable tmpDt = ds.Tables[tmpLine];
                        tmpDt.TableName = lineQuery.First<ProdLineSetting>().LineName;
                        foreach (DataRow tmpRow in tmpDt.Rows)
                        {
                            tmpRow["line_id"] = lineQuery.First<ProdLineSetting>().ID;
                            tmpRow["line_code"] = lineQuery.First<ProdLineSetting>().LineCode;
                            tmpRow["line_name"] = lineQuery.First<ProdLineSetting>().LineName;
                        }
                    }
                    else
                    {
                        tmpList.Add(tmpLine);
                        canSave = false;
                    }
                }

                if (tmpList != null && tmpList.Count > 0)
                {
                    List<string> lines = this._line_list.Select(l => l.LineName).ToList();
                    UpdateProdLineDia tmpDia = new UpdateProdLineDia(tmpList, lines);
                    tmpDia.ShowDialog();
                    Hashtable tmpHs = tmpDia.LineHs;
                    if (tmpHs != null && tmpHs.Count > 0)
                    {
                        foreach (DictionaryEntry item in tmpHs)
                        {
                            if (ds.Tables.Contains(item.Key.ToString()) && ds.Tables[item.Key.ToString()] != null)
                            {
                                string tmpLine = item.Value.ToString();
                                var lineQuery = this._line_list.Where(l => l.LineName == tmpLine);
                                if (lineQuery != null && lineQuery.Count() > 0)
                                {
                                    foreach (DataRow tmpRow in ds.Tables[item.Key.ToString()].Rows)
                                    {
                                        tmpRow["line_id"] = lineQuery.First<ProdLineSetting>().ID;
                                        tmpRow["line_code"] = lineQuery.First<ProdLineSetting>().LineCode;
                                        tmpRow["line_name"] = lineQuery.First<ProdLineSetting>().LineName;
                                    }
                                    ds.Tables[item.Key.ToString()].TableName = tmpLine;
                                }
                            }
                        }
                        this.cmbProdLine.Items.Clear();
                        foreach (DataTable dt in ds.Tables)
                        {
                            this.cmbProdLine.Items.Add(dt.TableName);
                        }
                    }
                }
            }
            return canSave;
        }

        /// <summary>
        /// 检查新增的排单计划中是否有异常存在
        /// </summary>
        /// <param name="scheduleList"></param>
        /// <returns></returns>
        private string CheckDataForInsert(List<ProdScheduleDTO> scheduleList)
        {
            string errStr = "";
            var targetQuery = scheduleList.Where(s => s.ProdID <= 0);
            if (targetQuery != null && targetQuery.Count() > 0)
            {
                errStr = "工单号：" + targetQuery.First().ProdNumber + "不存在于MES系统中！";
            }
            else
            {
                var groupQuery = scheduleList.GroupBy(s => new { s.LineName, s.ProdNumber }).Where(g => g.Count() > 1).SelectMany(g => g);
                if (groupQuery != null && groupQuery.Count() > 0)
                {
                    errStr = "生产线：" + groupQuery.First().LineName + "\r\n" + "工单号：" + groupQuery.First().ProdNumber + "\r\n" + "EXCEL表中有重复的记录！";
                }
                else
                {
                    foreach (var item in scheduleList)
                    {
                        if (item.LineName.Contains("SMT"))
                        {
                            if (item.ProdCycle == null || item.ProdCycle.ID <= 0)
                            {
                                errStr = "生产线：" + item.LineName + "\r\n" + "工单号：" + item.ProdNumber + "\r\n" + "该工单无法找到合适的交期设定(ProdCycle)！";
                                break;
                            }
                            else if (item.SourcePPCycle == null || item.SourcePPCycle.ID <= 0)
                            {
                                errStr = "生产线：" + item.LineName + "\r\n" + "工单号：" + item.ProdNumber + "\r\n" + "该工单没有交期明细(SourcePPCycle)！";
                                break;
                            }
                        }
                    }
                }
            }

            return errStr;
        }


        /// <summary>
        /// 查询时，将资料由类转化为DataTable
        /// </summary>
        /// <param name="list"></param>
        /// <returns></returns>
        private DataTable ListToDataTable(List<ProdScheduleDTO> list)
        {
            DataTable resDt = this.InitDataTableColumn();
            resDt.Columns.Add("is_choose", typeof(bool));

            int count = 0;
            if (list != null && list.Count > 0)
            {
                foreach (var item in list)
                {
                    DataRow addRow = resDt.NewRow();
                    addRow["is_choose"] = false;
                    addRow["index"] = count + 1;
                    addRow["id"] = item.ID;
                    addRow["line_id"] = item.LineID;
                    addRow["line_code"] = item.LineCode;
                    addRow["line_name"] = item.LineName;
                    addRow["fill_date"] = item.FillDate.ToString("yyyy-MM-dd");
                    addRow["target_id"] = item.ProdID;
                    addRow["prod_number"] = item.ProdNumber;
                    addRow["is_comp"] = item.IsComp == 1 ? true : false;
                    addRow["comp_date"] = item.CompDate.HasValue ? ((DateTime)item.CompDate).ToString("yyyy-MM-dd HH:mm:ss") : "";
                    addRow["remark"] = item.Remark;
                    addRow["remark_pmc"] = item.RemarkPMC;
                    addRow["is_del"] = item.IsDel;

                    addRow["saler_name"] = item.TargetProdProcess.SalerName;
                    addRow["client_code"] = item.TargetProdProcess.ClientCode;
                    addRow["mto_number"] = item.TargetProdProcess.MtoNumber;
                    addRow["mo_number"] = item.TargetProdProcess.MoNumber;
                    addRow["goods_number"] = item.TargetProdProcess.GoodsNumber;
                    addRow["old_number"] = item.TargetProdProcess.OldNumber;
                    addRow["goods_name"] = item.TargetProdProcess.GoodsName;
                    addRow["goods_spe"] = item.TargetProdProcess.GoodsSpe;
                    addRow["order_qty"] = Math.Round(item.TargetProdProcess.OrderQty ?? 0, 3);
                    addRow["goods_length"] = Math.Round(item.TargetProdProcess.GoodsLength ?? 0, 2);
                    addRow["prod_qty"] = Math.Round(item.TargetProdProcess.ProdQty ?? 0, 2);
                    resDt.Rows.Add(addRow);
                    count++;
                }
            }
            return resDt;
        }

        /// <summary>
        /// 清空界面
        /// </summary>
        private void ClearData()
        {
            this._ds.Tables.Clear();
            this.cmbProdLine.Items.Clear();
            this.dgvInsert.DataSource = this.InitDataTableColumn();
            //this.dgvSearch.DataSource = this.ListToDataTable(new List<ProdScheduleDTO>());
        }
        #endregion

        /// <summary>
        /// 内部类
        /// </summary>
        private class TableInfo
        {
            public int nameIndex { get; set; }
            public int titleIndex { get; set; }
            public int beginIndex { get; set; }
            public int endiIndex { get; set; }

        }



        private void btnOutput_Click(object sender, EventArgs e)
        {
            DateTime tmpDay = DateTime.Now;
            string basePath = Application.StartupPath + "\\排单计划";
            string fileName = "排单计划_" + tmpDay.ToString("yyyyMMdd") + "_" + tmpDay.ToString("HHmmss") + ".xlsx";

            List<int> idList = new List<int>();
            //if (this.dgvSearch.Rows.Count > 0)
            //{
            //    foreach (DataGridViewRow item in this.dgvSearch.Rows)
            //    {
            //        DataRow tmpRow = (item.DataBoundItem as DataRowView).Row;
            //        if (tmpRow["id"] != DBNull.Value && int.Parse(tmpRow["id"].ToString()) > 0)
            //        {
            //            idList.Add(int.Parse(tmpRow["id"].ToString()));
            //        }
            //    }
            //}

            List<ProdScheduleDTO> scheList = this._ctrl.SearchProdSchedureForID(idList);
            if (scheList != null && scheList.Count > 0)
            {
                this.OutputToExcel(basePath, fileName, scheList);
                UIMessageBox.ShowSuccess("排单计划已导出成功！");
                Process.Start(basePath);
            }
            else
            {
                UIMessageBox.ShowWarning("没有任何可以导出的排单计划！");
            }
        }


        private void OutputToExcel(string basePath, string fileName, List<ProdScheduleDTO> scheList)
        {
            if (System.IO.Directory.Exists(basePath) == false)
            {
                System.IO.Directory.CreateDirectory(basePath);
            }

            // 创建工作簿对象
            var workbook = new XSSFWorkbook();

            // 创建工作表对象
            var sheet = workbook.CreateSheet("排单计划");

            var titleStyle = workbook.CreateCellStyle();
            NPOI.SS.UserModel.IFont titleFont = workbook.CreateFont();
            titleFont.IsBold = true;
            titleFont.FontHeightInPoints = 18;
            titleStyle.BorderBottom = NPOI.SS.UserModel.BorderStyle.Thin;
            titleStyle.BorderTop = NPOI.SS.UserModel.BorderStyle.Thin;
            titleStyle.BorderLeft = NPOI.SS.UserModel.BorderStyle.Thin;
            titleStyle.BorderRight = NPOI.SS.UserModel.BorderStyle.Thin;
            titleStyle.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Center;
            titleStyle.VerticalAlignment = NPOI.SS.UserModel.VerticalAlignment.Center;
            titleStyle.WrapText = true;
            titleStyle.SetFont(titleFont);

            var bodyStyle = workbook.CreateCellStyle();
            NPOI.SS.UserModel.IFont matFont = workbook.CreateFont();
            matFont.IsBold = false;
            matFont.FontHeightInPoints = 10;
            bodyStyle.BorderBottom = NPOI.SS.UserModel.BorderStyle.Thin;
            bodyStyle.BorderTop = NPOI.SS.UserModel.BorderStyle.Thin;
            bodyStyle.BorderLeft = NPOI.SS.UserModel.BorderStyle.Thin;
            bodyStyle.BorderRight = NPOI.SS.UserModel.BorderStyle.Thin;
            bodyStyle.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Left;
            bodyStyle.VerticalAlignment = NPOI.SS.UserModel.VerticalAlignment.Top;
            bodyStyle.ShrinkToFit = true;
            bodyStyle.SetFont(matFont);

            var qtyStyle = workbook.CreateCellStyle();
            qtyStyle.DataFormat = HSSFDataFormat.GetBuiltinFormat("0.000");
            qtyStyle.BorderBottom = NPOI.SS.UserModel.BorderStyle.Thin;
            qtyStyle.BorderTop = NPOI.SS.UserModel.BorderStyle.Thin;
            qtyStyle.BorderLeft = NPOI.SS.UserModel.BorderStyle.Thin;
            qtyStyle.BorderRight = NPOI.SS.UserModel.BorderStyle.Thin;
            qtyStyle.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Center;
            qtyStyle.VerticalAlignment = NPOI.SS.UserModel.VerticalAlignment.Center;
            qtyStyle.ShrinkToFit = true;
            qtyStyle.SetFont(matFont);

            var dateStyle = workbook.CreateCellStyle();
            dateStyle.DataFormat = workbook.CreateDataFormat().GetFormat("yyyy-MM-dd");
            dateStyle.BorderBottom = NPOI.SS.UserModel.BorderStyle.Thin;
            dateStyle.BorderTop = NPOI.SS.UserModel.BorderStyle.Thin;
            dateStyle.BorderLeft = NPOI.SS.UserModel.BorderStyle.Thin;
            dateStyle.BorderRight = NPOI.SS.UserModel.BorderStyle.Thin;
            dateStyle.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Center;
            dateStyle.VerticalAlignment = NPOI.SS.UserModel.VerticalAlignment.Center;
            dateStyle.ShrinkToFit = true;
            dateStyle.SetFont(matFont);

            var compStyle = workbook.CreateCellStyle();
            compStyle.BorderBottom = NPOI.SS.UserModel.BorderStyle.Thin;
            compStyle.BorderTop = NPOI.SS.UserModel.BorderStyle.Thin;
            compStyle.BorderLeft = NPOI.SS.UserModel.BorderStyle.Thin;
            compStyle.BorderRight = NPOI.SS.UserModel.BorderStyle.Thin;
            compStyle.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Left;
            compStyle.VerticalAlignment = NPOI.SS.UserModel.VerticalAlignment.Top;
            compStyle.ShrinkToFit = true;
            compStyle.SetFont(matFont);
            compStyle.FillForegroundColor = NPOI.HSSF.Util.HSSFColor.LightGreen.Index;
            compStyle.FillPattern = NPOI.SS.UserModel.FillPattern.SolidForeground;


            List<int> widths = new List<int>(new int[] { 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13 });
            for (int i = 0; i < widths.Count; i++)
            {
                sheet.SetColumnWidth(i, widths[i] * 256);
            }

            List<string> titles = new List<string>(new string[] { "序号", "业务员", "计划跟踪号", "订单号", "工单单号", "主件品号", "型号规格", "订单数量", "单位", "生产性质", "长度", "投产数量", "备注" });

            int rowIndex = 1;
            foreach (var lineItem in scheList.Select(s => new { s.LineName, s.FillDate }).Distinct().OrderBy(s => s.FillDate).ToList())
            {
                List<ProdScheduleDTO> groupList = scheList.Where(s => s.LineName == lineItem.LineName && s.FillDate == lineItem.FillDate).OrderBy(s => s.ProdNumber).ToList();
                if (groupList != null && groupList.Count > 0)
                {
                    for (int i = rowIndex; i <= rowIndex + 6 + groupList.Count; i++)
                    {
                        var tmpRow = sheet.CreateRow(i);
                        for (int j = 0; j < titles.Count; j++)
                        {
                            var tmpCell = tmpRow.CreateCell(j);
                            tmpCell.CellStyle = bodyStyle;
                        }
                    }

                    sheet.AddMergedRegion(new CellRangeAddress(rowIndex, rowIndex + 1, 0, titles.Count - 1));
                    sheet.GetRow(rowIndex).GetCell(0).SetCellValue(lineItem.LineName + "生产计划");
                    sheet.GetRow(rowIndex).GetCell(0).CellStyle = titleStyle;


                    sheet.GetRow(rowIndex + 2).GetCell(10).SetCellValue("计划发放日期：" + lineItem.FillDate.ToString("yyyy-MM-dd"));
                    sheet.AddMergedRegion(new CellRangeAddress(rowIndex + 2, rowIndex + 2, 0, 9));
                    sheet.AddMergedRegion(new CellRangeAddress(rowIndex + 2, rowIndex + 2, 10, titles.Count - 1));


                    for (int i = 0; i < titles.Count; i++)
                    {
                        sheet.GetRow(rowIndex + 3).GetCell(i).SetCellValue(titles[i]);
                    }

                    int count = 0;
                    decimal totalQty = 0;
                    decimal totalLength = 0;


                    foreach (var item in groupList)
                    {
                        //sheet.GetRow(rowIndex + 4 + count).RowStyle = bodyStyle;
                        sheet.GetRow(rowIndex + 4 + count).GetCell(0).SetCellValue(count + 1);
                        sheet.GetRow(rowIndex + 4 + count).GetCell(1).SetCellValue(item.TargetProdProcess.SalerName);
                        sheet.GetRow(rowIndex + 4 + count).GetCell(2).SetCellValue(item.TargetProdProcess.MtoNumber);
                        sheet.GetRow(rowIndex + 4 + count).GetCell(3).SetCellValue(item.TargetProdProcess.MoNumber);
                        sheet.GetRow(rowIndex + 4 + count).GetCell(4).SetCellValue(item.ProdNumber);
                        sheet.GetRow(rowIndex + 4 + count).GetCell(5).SetCellValue(item.TargetProdProcess.GoodsNumber);
                        sheet.GetRow(rowIndex + 4 + count).GetCell(6).SetCellValue(item.TargetProdProcess.GoodsSpe);
                        sheet.GetRow(rowIndex + 4 + count).GetCell(7).SetCellValue(Convert.ToDouble(Math.Round(item.TargetProdProcess.OrderQty ?? 0, 3)));
                        //sheet.GetRow(rowIndex + 4 + count).GetCell(7).CellStyle = qtyStyle;
                        sheet.GetRow(rowIndex + 4 + count).GetCell(8).SetCellValue("Psc");
                        sheet.GetRow(rowIndex + 4 + count).GetCell(9).SetCellValue("");
                        sheet.GetRow(rowIndex + 4 + count).GetCell(10).SetCellValue(Convert.ToDouble(Math.Round(item.TargetProdProcess.GoodsLength ?? 0, 3)));
                        //sheet.GetRow(rowIndex + 4 + count).GetCell(10).CellStyle = qtyStyle;
                        sheet.GetRow(rowIndex + 4 + count).GetCell(11).SetCellValue(Convert.ToDouble(Math.Round(item.TargetProdProcess.ProdQty ?? 0, 3)));
                        //sheet.GetRow(rowIndex + 4 + count).GetCell(11).CellStyle = qtyStyle;
                        sheet.GetRow(rowIndex + 4 + count).GetCell(12).SetCellValue(item.Remark);
                        totalQty += Math.Round(item.TargetProdProcess.GoodsLength ?? 0, 3);
                        totalLength += Math.Round((item.TargetProdProcess.GoodsLength ?? 0) * (item.TargetProdProcess.ProdQty ?? 0), 3);

                        if (item.IsComp == 1)
                        {
                            for (int i = 0; i < titles.Count; i++)
                            {
                                sheet.GetRow(rowIndex + 4 + count).GetCell(i).CellStyle = compStyle;
                            }
                        }

                        count++;
                    }

                    //sheet.GetRow(rowIndex + 4 + count).RowStyle = bodyStyle;
                    sheet.GetRow(rowIndex + 4 + count).GetCell(0).SetCellValue("合计：");
                    sheet.GetRow(rowIndex + 4 + count).GetCell(12).SetCellValue(Convert.ToDouble(totalLength));

                    rowIndex = rowIndex + 7 + count;
                }
            }
            using (var fileStream = new FileStream(basePath + "\\" + fileName, FileMode.Create))
            {
                workbook.Write(fileStream);
            }
        }

    }
}
